-
Notifications
You must be signed in to change notification settings - Fork 285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow individual fences to be enabled and disabled #349
Conversation
6712c51
to
36f30e0
Compare
d0fa1b3
to
bf3012a
Compare
@hamishwillee can you have a quick look - I think this is good to go, if you agree I'll pull it across to mavlink/mavlink |
@auturgy Looks good to me. Once this is in mavlink/mavlink there might be differing opinions. |
Yes, although that's not actually the problem I am trying to solve
The main issue is that ALT_MIN fences cannot be simply enabled and disabled at the same time as all the others. If you are on the ground you only want to enable the fences that make sense (for instance). In the air you might want something different. A single big fat enable flag makes all of this logic extremely convoluted - you have to have all kinds of exceptions to things. This allows the mavlink commands to actually DWIS as well as DWIM
Yes I agree, but history
|
Ah, so geofences are all default on. Your first mission item might be to disable the minimum alt fence. Then once flying enable all, and disable just the minimum fence again to land? For takeoff I guess you might have some rule that says minimum fences don't apply until you have first exceeded them, but you'd still need some way to turn them off again in order to land. So this makes sense. @auturgy I'm good with this. |
So if we want to change the fence type (e.g. turn off
Should we also add a new value to
|
@@ -1305,7 +1322,7 @@ | |||
<entry value="207" name="MAV_CMD_DO_FENCE_ENABLE" hasLocation="false" isDestination="false"> | |||
<description>Mission command to enable the geofence</description> | |||
<param index="1" label="Enable" minValue="0" maxValue="2" increment="1">enable? (0=disable, 1=enable, 2=disable_floor_only)</param> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worth converting this to an enum
while we're here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also add a new value to p1 called e.g. SET_FROM_BITMASK such that we could combine the above into:
I quite like that idea. It is more inline with how I think of bitmasks. Also it ompletely separates the old behaviour from the new behaviour so the bitmasks are only used with that new param 1.
We'd have to check no one is doing something annoying like treating any non-zero value of param 1 as enabled.
Is it worth converting this to an enum while we're here?
Probably. If we do this it makes it easier to more clearly deprecate particular options, such as param1 option "2" over time.
But let's see what @andyp1per and others think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea, but I think you need both - otherwise you need to make a call to find out what the current bitmask is.
So I think setting enable/disable with a bitmask should still be valid and then a new option which overwrites everything
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand this ^^^. Why do you need to know the current bitmask? Whatever you set will become the enabled/disabled state with the new approach?
The other thing I like about using a bitmask in this way is that we could make it a proper bitmask - ie. not use 0 to mean "set all" but instead set nothing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets say I only want to change the max altitude fence. I need to know whether any of the other fences are enabled because I want to preserve their state - I have to find that out from somewhere or stash it. With the enable/disable thing I don't need to remember this because I know I am only changing one specific fence - which TBH is the whole point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andyp1per Doh - thanks.
So to be clear, the only use case you really need here is to be able to disable the altitude geofence on takeoff, enable it again when flying, then disable it for landing?
If so, why can't you:
- Before takeoff send command with
param1 = 2
- disables the floor check so you can take off - When flying send command with
param=1
- enable all - Before landing send command with
param1 = 2
- disables the floor check
I appreciate this new approach is more flexible but I don't see why you'd ever want to selectively turn on/off the other case.
Sorry if I'm being dumb here. We can skype if you like - hamishgw
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ultimately I want this to be finely controlled from scripting. Individually enabling and disabling notches is a requirement here. We also have tests that test individual fences in the air - I don't want to break that behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"I want to because I have requirements and tests" doesn't sound like a use case - it is easy to create a bogus requirement and then test against it". Can you give me one real case where you're flying and you want to disable all circle fences but not all polygon fences, and visa versa? I'm asking because the change should add value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am at a race track. I have a polygon fence around the track and a circle fence around the landing area. I want the polygon fence to always be active but I want the landing area to be deactivated on a switch when I am ready to come in to land.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's pretty inflexible. I only have to add one more fence of any kind to mean that this no longer works.
@@ -1305,7 +1322,7 @@ | |||
<entry value="207" name="MAV_CMD_DO_FENCE_ENABLE" hasLocation="false" isDestination="false"> | |||
<description>Mission command to enable the geofence</description> | |||
<param index="1" label="Enable" minValue="0" maxValue="2" increment="1">enable? (0=disable, 1=enable, 2=disable_floor_only)</param> | |||
<param index="2">Empty</param> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an aside, what's your understanding the conditions under which the fences revert to their system defaults (presumably "all enabled").
For missions I think it is pretty straightforward - generally settings in missions should revert to system defaults when the mode changes out of mission mode - although this is problematic for for flight stacks that implement mission pause as a mode change, since the current setting would be lost.
I'm not sure about what happens if this is sent in a command, and the docs don't say.
- It could be that when sent as a command this permanently changes the system default - i.e. it turns off the fences even if defined in the mission. If so, we'd need a way to know whether they are on or off.
- It could be that when sent as a command the change is temporary for the current mode. So (thinking in PX4 as more familiar for me) you'd set takeoff mode, send command to disable the altitude fence, arm and takeoff. The fence would then turn on as you switch from takeoff to hold. Or similar.
- Something else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the things I am trying to fix is that mavlink currently makes permanent changes to the vehicle defaults - I want to support not doing this. My design assumption was that with this, whatever was sent from mavlink should override whatever is currently configured. We also have parameters relating to auto-enablement that are not reflected in mavlink - not permanently updating makes this a bit easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see benefits to either approach - setting the system defaults or a temporary change. It's not my call which is used, and I don't "care" provided the behaviour is specified, and the specification does not immediately make either ArduPilot or PX4 non-compliant (as that needs to be agreed/managed).
Assuming all are OK with this this case the description might change from:
<description>Mission command to enable the geofence</description>
to
<description>
Enable the geofence.
This can be used in a mission or via the command protocol.
The effects persist while the mission is being executed, until superseded by another mission item or the mission completes.
When used as a command (outside of mission) the value persists until superseded by another command, a mode change (which reverts system back to system defaults), or reboot.
When used as a command while a mission is running the value is treated as though it were a mission item, and will change the current mission value.</description>
The points of interest being that:
- mission settings persist in the mission context, even on flight stacks that pause by switching mode to "Hold": on return to the mission the mission setting would be used.
- As a command the value only persists until mode change or reboot.
- A command can affect a mission
All of that is arguable, but IMO should be the default thinking for commands used in both missions and command protocol.
If you think this is reasonable I'll create an upstream PR to discuss.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable to me
<param index="2" label="Types" enum="FENCE_TYPE">Fence types to enable or disable as a bitmask. A value of 0 indicates that all fences should be enabled or disabled. This parameter is ignored if param 1 has the value 2</param> | ||
<param index="3">Empty</param> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andyp1per For discussion, there is another way that this can be done, which might be better - two enums, one being a bitmask that says what you're enabling.
This allows you to specify any combination of flags to be enabled/disabled. It means, for example, that you don't have do know whether a particular fence type is enabled or disabled to start with, you can just use the second bitmask to specify that you're only interested in affecting the altitude floor fence (say).
We'd enable this completely separate of the original behaviour using param1=4
So something like:
<param index="2" label="Types" enum="FENCE_TYPE">Fence types to enable or disable as a bitmask. A value of 0 indicates that all fences should be enabled or disabled. This parameter is ignored if param 1 has the value 2</param> | |
<param index="3">Empty</param> | |
<param index="2" label="Types" enum="FENCE_TYPE">A bitmask of the fence types to enable and disable (i.e. a value of 0 indicates that all fences should disabled). Values are only changed if the corresponding type in param 3 is set. This param is ignored unless param1=4.</param> | |
<param index="3" label="Types bitmask" enum="FENCE_TYPE">Bitmask indicating the fence types in param2 that are affected. If 0, no fences are affected. This parameter is ignored unless param1=4.</param> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tomato, tomato - I think my way is better, but as long as I can get the functionality I am after - enabling and disabling of individual fences I don't really care. I'm not quite clear what happens to current calls with your scheme and the default values - does it really work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should.
I'm not quite clear what happens to current calls with your scheme and the default values - does it really work?
I'm not certain what you mean, but the new stuff would all be conditional on param1 = 4. Existing systems should reject a command with this value.
@auturgy @andyp1per I don't believe this particular implementation to address the stated use case is necessary.
Something more useful would be an approach for enabling/disabling an arbitrary set of inclusion and/or exclusion fences. |
Disagree. We would use something similar to #349 (comment) during flight testing is this was available:
Yes, that would be more useful, but that capability doesn't exist now. I don't think you should reject a solution that works because there might be a better solution in the future. |
bf3012a
to
d4c3bf8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No objections from my side.
Thanks. I'll make the upstream PR unless someone else beats me to it. |
Thanks all! |
* from ArduPilot#349 * typo * common: fix formatting Signed-off-by: Julian Oes <[email protected]> --------- Signed-off-by: Julian Oes <[email protected]> Co-authored-by: Julian Oes <[email protected]>
Allows a bitmask to be passed to the fence enable function to specify individual fences to enable or disable
This has been done so that by not providing the second arg you get the current behaviour which is to enable and disable all fences